/*
 * XInput1_3-dev - Replacement of xinput library to help with creating
 *                 drivers/debugging application
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.
 */

#pragma once

#include <SetupAPI.h>

#pragma pack(push, 1)
struct GamepadState0100
{
	BYTE bEnabled; //0
	BYTE bUnknown; //1
	BYTE Dummy2;   //2
	WORD dwPacketNumber; //3
	XINPUT_GAMEPAD Gamepad; //4
	WORD Dummy16; // 16
	WORD Dummy18; // 18
};

struct GamepadState0101
{
	WORD Dummy0;   //0
	BYTE bEnabled; //2
	BYTE Dummy3;   //3
	BYTE Dummy4;   //4
	DWORD dwPacketNumber; //5
	WORD Dummy9; //9
	XINPUT_GAMEPAD Gamepad; //11
	WORD Dummy23; // 23
	WORD Dummy25; // 25
	WORD Dummy27; // 27
};

struct GamepadCapabilities0101
{
	WORD Dummy0;      //0
	BYTE Type;        //2
	BYTE SubType;     //3

	// XINPUT_GAMEPAD
	WORD                                wButtons; //4
    BYTE                                bLeftTrigger; //6
    BYTE                                bRightTrigger; //7
    SHORT                               sThumbLX; //8
    SHORT                               sThumbLY; //10
    SHORT                               sThumbRX; //12
    SHORT                               sThumbRY; //14
	WORD Dummy16; //16
	WORD Dummy18; //18
	WORD Dummy20; //20

	// Vibration
	BYTE bLeftMotorSpeed; //22
	BYTE bRightMotorSpeed; //23
};
#pragma pack(pop)

typedef BOOL (WINAPI *FnDeviceIoControl_t)(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPDWORD lpBytesReturned, LPOVERLAPPED lpOverlapped);
extern FnDeviceIoControl_t g_pfnDeviceIoControl;

GamepadState0100 *CopyGamepadStateToDeviceInfo(PDEVICE_INFO *,GamepadState0100 *);
GamepadState0101 *CopyGamepadStateToDeviceInfo(PDEVICE_INFO *,GamepadState0101 *);
PXINPUT_CAPABILITIES TranslateCapabilities(GamepadCapabilities0101 const *,_XINPUT_CAPABILITIES *);
HRESULT SendReceiveIoctl(HANDLE hDevice, DWORD dwIoControlCode, LPVOID lpInBuffer, DWORD nInBufferSize, LPVOID lpOutBuffer, DWORD nOutBufferSize, LPOVERLAPPED lpOverlapped);
HRESULT SendIoctl(void *,ulong,uchar *,ulong);
HRESULT ReceiveIoctl(void *,ulong,uchar *,ulong);

namespace DriverComm
{
	struct XINPUT_AUDIO_INFORMATION
	{
	};

	HRESULT CancelGuideButtonWait(tagDeviceInfo *);
	BOOL CheckForDriverHook(ulong,void *);
	HRESULT GetAudioDeviceInformation(tagDeviceInfo *, XINPUT_AUDIO_INFORMATION *);
	HRESULT GetBatteryInformation(tagDeviceInfo *,uchar,_XINPUT_BATTERY_INFORMATION *);
	HRESULT GetCapabilities(tagDeviceInfo *,_XINPUT_CAPABILITIES *);
	HRESULT GetDeviceInfoFromInterface(HANDLE hDevice, PINTERFACE_INFORMATION pInterfaceInformation);
	HRESULT GetLEDState(tagDeviceInfo *,uchar *);
	HRESULT GetLatestDeviceInfo(tagDeviceInfo *);
	HRESULT Initialize(void);
	HRESULT PowerOffController(tagDeviceInfo *);
	HRESULT SendDeviceVibration(tagDeviceInfo *);
	HRESULT SendLEDState(tagDeviceInfo *,uchar);
	HRESULT WaitForGuideButton(void *,uchar, XINPUT_LISTEN_STATE *);

	namespace SetupDiWrapper
	{
		BOOL DestroyDeviceInfoList(HDEVINFO DeviceInfoSet);
		BOOL EnumDeviceInterfaces(HDEVINFO DeviceInfoSet, PSP_DEVINFO_DATA DeviceInfoData, const GUID *InterfaceClassGuid, DWORD MemberIndex, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData);
		HDEVINFO GetClassDevs(const GUID *ClassGuid, PCWSTR Enumerator, HWND hwndParent, DWORD Flags);
		BOOL GetDeviceInterfaceDetail(HDEVINFO DeviceInfoSet, PSP_DEVICE_INTERFACE_DATA DeviceInterfaceData, PSP_DEVICE_INTERFACE_DETAIL_DATA_W DeviceInterfaceDetailData, DWORD DeviceInterfaceDetailDataSize, PDWORD RequiredSize, PSP_DEVINFO_DATA DeviceInfoData);
	}
}